package com.demo.rpc.server;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class RpcServer {


    public void start(int port, String clazz) {
        ServerSocket server = null;
        try {
            //创建socket连接
            server = new ServerSocket(port);
            Map<String,Object> services = getService(clazz);
            Executor executor = new ThreadPoolExecutor(5,10,10, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>());
            while (true){
                Socket client = server.accept();
                RpcService service = new RpcService(client,services);
                executor.execute(service);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (server != null) {
                try {
                    server.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public Map<String, Object> getService(String clazz) {
        try {
            Map<String, Object> services = new HashMap<>();
            String[] clazzes = clazz.split(",");
            List<Class<?>> classes = new ArrayList<>();
            for (String cl : clazzes) {
                List<Class<?>> classList = getClasses(cl);
                classes.addAll(classList);
            }
            //循环实例化
            for (Class<?> cla : classes) {
                Object obj = cla.newInstance();
                services.put(cla.getAnnotation(com.demo.rpc.annoation.RpcService.class).value().getName(), obj);
            }
            return services;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static List<Class<?>> getClasses(String pckgname) throws ClassNotFoundException {
        List<Class<?>> classes = new ArrayList<>();
        File directory = null;
        ClassLoader cld = Thread.currentThread().getContextClassLoader();
        if (cld == null) {
            throw new ClassNotFoundException("Can`t get class loader ..");
        }
        String path = pckgname.replace(".", "/");
        URL resource = cld.getResource(path);
        if (resource == null) {
            throw new ClassNotFoundException("No resource for " + path);
        }
        directory = new File(resource.getFile());
        if (!directory.exists()) {
            throw new ClassNotFoundException(pckgname + "dons not appear to be a valid package name");
        }
        String[] files = directory.list();
        File[] fileList = directory.listFiles();
        for (int i = 0; fileList != null && i < fileList.length; i++) {
            File file = fileList[i];
            if (file.isFile() && file.getName().endsWith(".class")) {
                assert files != null;
                Class<?> clazz = Class.forName(pckgname + '.' + files[i].substring(0, files[i].length() - 6));
                if (clazz.getAnnotation(com.demo.rpc.annoation.RpcService.class) != null) {
                    classes.add(clazz);
                }
            } else if (file.isDirectory()) {
                //如果是目录则递归查询
                List<Class<?>> result = getClasses(pckgname + "." + file.getName());
                if (result != null && result.size() != 0) {
                    classes.addAll(result);
                }

            }
        }
        return classes;
    }

}
